package com.itheima.ydd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.ydd.common.R;
import com.itheima.ydd.dto.PageInfo;
import com.itheima.ydd.dto.RoleDto;
import com.itheima.ydd.dto.SysMenuDto;
import com.itheima.ydd.mapper.SysMenuMapper;
import com.itheima.ydd.mapper.SysRoleMapper;
import com.itheima.ydd.pojo.SysMenu;
import com.itheima.ydd.pojo.SysRole;
import com.itheima.ydd.pojo.SysRoleMenu;
import com.itheima.ydd.pojo.SysUser;
import com.itheima.ydd.service.SysMenuService;
import com.itheima.ydd.service.SysRoleMenuService;
import com.itheima.ydd.service.SysRoleService;
import com.itheima.ydd.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    @Autowired
    private SysRoleMenuService srmService;
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    private SysUserService userService;

    //修改角色
    @Override
    public ResponseEntity<R<String>> updateSysRole(RoleDto roleDto) {
        log.info("修改方法开始执行");
        //先修改role表
        updateById(roleDto);
        //再对rolrMenu表对应的数据先删除,再添加;因为修改一对一,很明显这里是一个集合替换另一个集合
        List<Integer> menuIds = roleDto.getMenuIds();
        //防止错删其他用户的信息
        if (menuIds == null) return ResponseEntity.ok(R.success("修改失败"));
        srmService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleDto.getId()));
        List<SysRoleMenu> roleMenus = new ArrayList<>();

        for (Integer menuId : menuIds) {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleDto.getId());
            roleMenu.setMenuId(menuId.toString());
            roleMenus.add(roleMenu);
        }
        srmService.saveBatch(roleMenus);
        return ResponseEntity.ok(R.success("修改成功"));
    }

    //添加角色
    @Override
    public ResponseEntity<R<String>> addSysRole(RoleDto roleDto) {
        //先添加一个Sysrole
        SysRole role = new SysRole();
        role.setName(roleDto.getName());
        role.setDescription(roleDto.getDescription());
        save(role);
        //再添加对应的SysroleMenu
        List<Integer> menuIds = roleDto.getMenuIds();
        log.info(menuIds + "");
        List<SysRoleMenu> roleMenus = new ArrayList<>();
        for (Integer menuId : menuIds) {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(role.getId());
            roleMenu.setMenuId(menuId.toString());
        }
        srmService.saveBatch(roleMenus);
        return ResponseEntity.ok(R.success("添加成功"));
    }

    //删除角色
    @Override
    public ResponseEntity<R<String>> delSysRole(String id) {
        //id不能是null,会报错,这里提前判断
        if (id == null) return ResponseEntity.ok(R.err("删除失败,查无此id"));
        //是否有用户的roleID包含id,有就说明该角色下有用户
        int count = userService.count(new LambdaQueryWrapper<SysUser>().like(SysUser::getRoleId, id));
        if (count > 0) return ResponseEntity.ok(R.err("删除失败,该角色下还有用户"));
        //没有直接删,还要删对应的roleMenu表
        removeById(id);
        srmService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, id));
        return ResponseEntity.ok(R.success(null));
    }

    @Override
    /**
     * @param page 页码
     * @param limit 每页数量
     * @param name  角色名称,支持模糊查询
     */
    public ResponseEntity<R<PageInfo<SysRole>>> findPageOrName(Integer page, Integer limit, String name) {
        //设置分页参数
        IPage<SysRole> pg = new Page<SysRole>(page, limit);
        //条件对象
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        //判断name是否为空    "" "  " null 都是false
        wrapper.like(StringUtils.hasText(name), SysRole::getName, name);
        //设置排序规则
        wrapper.orderByDesc(SysRole::getUpdateDate);
        //分页查询
        page(pg, wrapper);
        PageInfo<SysRole> pageInfo = new PageInfo<>();
        //将数据封装到pageinfo新对象中
        pageInfo.setCount((int) pg.getTotal());
        pageInfo.setTotalPages((int) pg.getPages());
        pageInfo.setPageSize((int) pg.getSize());
        pageInfo.setCurrentPage((int) pg.getCurrent());
        pageInfo.setData(pg.getRecords());
        return ResponseEntity.ok(R.success(pageInfo));
    }

    /**
     * 查询所有
     *
     * @return
     */
    @Override
    public ResponseEntity<R<List<SysRole>>> findAllData() {
        List<SysRole> list = list();
        return ResponseEntity.ok(R.success(list));
    }

    @Override
    public ResponseEntity<R> findById(String id) {
        SysRole sysRole = getById(id);
        RoleDto roleDto = new RoleDto();
        BeanUtils.copyProperties(sysRole, roleDto);
        // 查询角色所包含菜单并存入角色
        getList(roleDto);
        if (roleDto.getMenuIds() == null) return ResponseEntity.ok(R.err("该用户要么是假数据,要么没功能"));
        return ResponseEntity.ok(R.success(roleDto));
    }

    private void getList(RoleDto roleDto) {
        // 查询角色根菜单
        List<SysMenu> parentList = roleMapper.selectParentList(roleDto.getId());

        if (parentList.isEmpty()) {
            return;
        }

        List<SysMenuDto> authList = parentList.stream().map(menu -> {
            // 查询每个根菜单的子菜单
            List<SysMenuDto> childMenuDtoList = selectChildList(roleDto.getId(), menu.getId());
            SysMenuDto menuDto = new SysMenuDto();
            BeanUtils.copyProperties(menu, menuDto);
            menuDto.setChildren(childMenuDtoList);
            return menuDto;
        }).collect(Collectors.toList());
        roleDto.setAuthList(authList);
    }

    private List<SysMenuDto> selectChildList(String roleId, Integer id) {
        List<SysMenu> childMenuList = roleMapper.selectChildList(roleId, id);
        if (childMenuList.isEmpty()) {
            return null;
        }
        List<SysMenuDto> menuDtoList = childMenuList.stream().map(menu -> {
            SysMenuDto menuDto = new SysMenuDto();
            BeanUtils.copyProperties(menu, menuDto);
            // 递归查询
            menuDto.setChildren(selectChildList(roleId, menu.getId()));
            return menuDto;
        }).collect(Collectors.toList());
        return menuDtoList;
    }

}
